/*
 * AbstractGenerator.java
 *
 * Created on Piatok, 2007, november 2, 18:49
 *
 */

package logic.distributions;

import java.util.Collection;
import java.util.Vector;

/**
 * Trieda zastresujuca generatory nahodnych cisel. Obsahuje nazvy parametrov
 * generatora a jeho hodnoty.
 *
 * @author alvin
 */
public abstract class AbstractGenerator {
    Vector<String> names;
    Vector<Object> values;
    
    
    public AbstractGenerator() {
        names = generateParameterNames();
        values = new Vector<Object>(names.size());
        for (int i = 0; i < names.size(); i++) {
            values.add(null);
        }
        initValues();
    }
   
    public final int getParamsCount() {
        return names.size();
    }
    
    /**
     * Vygenerovanie zobrazitelnych nazvov parametrov
     */
    protected abstract Vector<String> generateParameterNames();
    
    /**
     * Inicializacia hodnot vo vektore values. Moze to byt
     * volanie setUncheckedParameter() pre vsetky parametre.
     */
    public abstract void initValues();
    
    /**
     * Vracia zobrazitelny nazov parametra rozdelenia.
     */
    public String getParameterName(int index) {
        return names.get(index);
    }

    /**
     * Vracia parameter s danym indexom. Odporucany typ vystupu je String.
     */
    public Object getParameter(int index) {
        return values.get(index);
    }
    
    /**
     * Skontroluje, ci je mozne dany parameter nastavit na novu hodnotu.
     * Ak to nie je mozne, vrati popis chyby. Inak vracia null.
     * Hodnota index bude od 0 po getParamsCount()-1.
     * Hodnota value bude rozna od null.
     */
    public abstract String checkParameter(int index, Object value);
    
    /**
     * Pokusi sa nastavit dany parameter na novu hodnotu. Ak
     * metoda checkParameter(index, value) vrati nenulovu hodnotu,
     * vyhodi Exception.
     */
    public final void setParameter(int index, Object value) throws Exception {
        if ((index < 0) || (index > getParamsCount() - 1))
            throw new Exception("Invalid index " + index);
        if (value == null)
            throw new Exception("Value must be not equal to null");
        if (checkParameter(index, value) != null) {
            throw new Exception(checkParameter(index, value));
        }
        values.setElementAt(value, index);
    }

    /**
     * Nastavenie daneho parametra bez kontroly.
     */
    protected void setUncheckedParameter(int index, Object value) {
        values.setElementAt(value, index);
    }
    
    /**
     * @return Textova podoba vsetkych parametrov - potrebna pre ulozenie
     */
    public Vector<String> getAllParameters() {
        Vector<String> result = new Vector<String>(values.size());
        for (Object elem : values)
            result.add(elem.toString());
        return result;
    }
    
    /**
     * Nastavenie parametrov generatora podla nacitanych retazcov.
     */
    public void setAllParameters(Vector<String> parameters) {
        for (int i = 0; i < parameters.size(); i++) {
            values.setElementAt(parameters.get(i),i);
        }
    }
    
    /**
     * Vrati nazov typu generatora.
     */
    public abstract String getTypeString();
    
    /**
     * Inicializacia vnutorneho generatora. Musi sa zavolat pred ziadanim hodnoty.
     * Nastavuje generatoru dane meno.
     */
    public abstract void initGenerator(String generatorName);

    /**
     * Vracia true, ak je generator diskretny.
     */
    public abstract boolean isDiscreteGenerator();
    
    /**
     * Vracia novu hodnotu diskretneho generatora. Ak je generator spojity,
     * vrati zaokruhlenu hodnotu.
     */
    public abstract long getDiscreteValue();
    
    /**
     * Vracia novu hodnotu spojiteho generatora. Ak je generator diskertny,
     * vrati pretypovanu hodnotu.
     */
    public abstract double getContinuousValue();

}
